<template>
  <block>
    <view class="c-pload" :class="ggclass" v-if="type === 'image'">
      <view class="img-box" v-for="(v, i) in val" :key="i">
        <image
          class="img"
          :style="{ borderRadius: radius, width, height }"
          :src="imgFilter(v)"
          @click="onImage(imgFilter(v))"
        >
        </image>
        <text class="iconfont icon-guanbi1" @click="dele(v, i)"></text>
      </view>
      <view
        v-if="isUp"
        class="upload-button"
        @click="upload"
        :style="{ borderRadius: radius, width, height }"
      >
        <c-icon icon="icon-jiahao" color="#ccc" :size="fontSize"></c-icon>
        <!-- <text class="iconfont " color="#ccc" :size="fontSize"></text> -->
      </view>
    </view>
    <view class="c-pload" :class="ggclass" v-else>
      <view class="img-box" v-for="(v, i) in val" :key="i">
        <video
          class="img"
          id="video"
          :style="{ borderRadius: radius, width, height }"
          :src="imgFilter(v)"
          @click="onVideo"
          :controls="controls"
          @fullscreenchange="fullscreenchange"
          :muted="ismuted"
          :initial-time="0.01"
          :direction="0"
          :object-fit="objectFit"
        ></video>
        <text class="iconfont icon-guanbi" @click="dele(v, i)"></text>
      </view>
      <view
        v-if="isUp"
        class="upload-button"
        @click="upload"
        :style="{ borderRadius: radius, width, height }"
      >
        <uni-icons type="plusempty" color="#ccc" :size="fontSize"></uni-icons>
      </view>
    </view>
  </block>
</template>

<script setup lang="ts">
import {
  defineProps,
  reactive,
  watch,
  inject,
  getCurrentInstance,
  computed,
  toRefs,
} from "vue";
const { proxy } = getCurrentInstance() as any;
//@ts-ignore
import { defaultAvatar } from "../../static/img/base64.js";
//@ts-ignore
import { imgPreview } from "../ways/img.js";
import { imgFilter } from "../ways/filter";
const Cinput = inject("Cinput") as any;
const props = defineProps({
  type: {
    type: String,
    default: "image",
  },
  maxCount: {
    type: Number,
    default: 1,
  },
  ggclass: {
    type: String,
    default: "",
  },
  radius: {
    type: String,
    default: "",
  },
  width: {
    type: String,
    default: "",
  },
  height: {
    type: String,
    default: "",
  },
  modelValue: {
    type: String,
    default: "",
  },
  api: {
    type: String,
    default: "/upload/image",
  },
  vapi: {
    type: String,
    default: "/upload/video",
  },
  isPreview: {
    type: Boolean,
    default: false,
  },
  isUpload: {
    type: Boolean,
    default: true,
  },
  videoSize: {
    //视频大小
    Number,
    default: 30,
  },
  maxDuration: {
    //拍摄视频最长拍摄时间，单位秒。最长支持 60 秒。
    Number,
    default: 10,
  },
  range_key: {
    type: String,
    default: "url",
  },
});
const state = reactive<{
  objectFit: string; //是否裁剪
  ismuted: boolean; //是否静音。
  isFullscreen: boolean; //是否全屏。
  val: Array<string>;
  videoContext: any;
  controls: boolean;
}>({
  objectFit: "cover", //是否裁剪
  ismuted: true, //是否静音。
  isFullscreen: false, //是否全屏。
  val: [],
  videoContext: {},
  controls: false,
});
const {objectFit, ismuted, isFullscreen, val, videoContext, controls} = toRefs(state)
watch(
  () => props.modelValue,
  (n) => {
    let imgurl: Array<string> = [];
    if (!n) {
    } else if (Array.isArray(n)) {
      imgurl = n;
    } else {
      imgurl = n.split(",");
    }
    state.val = new Proxy(imgurl, {
      get: (item: any, key) => {
        return item[key];
      },
      set: (item: any, key, value) => {
        item[key] = value;
        if (Array.isArray(n)) {
          proxy.$emit("input", item);
          proxy.$emit("change", item);
        } else {
          proxy.$emit("input", item.join(","));
          proxy.$emit("change", item.join(","));
        }
        return true;
      },
      deleteProperty: (target: any, property) => {
        if (Array.isArray(n)) {
          proxy.$emit("input", target);
          proxy.$emit("change", target);
        } else {
          proxy.$emit("input", target.join(","));
          proxy.$emit("change", target.join(","));
        }
        return Reflect.deleteProperty(target, property);
      },
    });
    if (props.type === "video") {
      proxy.$nextTick(() => {
        state.videoContext = uni.createVideoContext("video", proxy);
      });
    }
  },
  { immediate: true, deep: true }
);

const isUp = computed(() => {
  if (state.val.length < props.maxCount && props.isUpload) {
    return true;
  }
  return false;
});
// val: {
// 	get() {

// 	},
// 	set(val) {
// 		// this.imgList = val
// 		// console.log(val, '---')
// 		// if (Array.isArray(this.value)) {
// 		// 	this.$emit('input', val)
// 		// 	this.$emit('change', val)
// 		// } else {
// 		// 	this.$emit('input', val.join(','))
// 		// 	this.$emit('change', val.join(','))
// 		// }
// 	}
// },
const fontSize = computed(() => {
  return `${parseInt(props.width || "150") / 2}rpx`;
});

const dele = (v: any, i: number) => {
  state.val.splice(i, 1);
};
const onImage = (event:any) => {
  if (props.isPreview) {
    imgPreview(event);
  }
  proxy.$emit("click", event);
  proxy.$emit("tap", event);
};
const fullscreenchange = (e: any) => {
  if (e.detail.fullScreen) {
    state.ismuted = false;
    state.objectFit = "contain";
    state.isFullscreen = true;
  } else {
    state.objectFit = "cover";
    state.ismuted = true;
    state.isFullscreen = false;
  }
};
const onVideo = () => {
  if (state.isFullscreen) {
    state.videoContext.exitFullScreen();
    state.videoContext.stop();
  } else {
    state.videoContext.requestFullScreen();
    state.videoContext.play();
  }
};
const upload = async () => {
  let result = null;
  if (props.type === "image") {
    result = await chooseImg();
  } else {
    result = await chooseVideo();
  }
  let pArr: Array<Promise<any>> = [];
  result.forEach(async (v: any) => {
    pArr.push(uploadFile(v.path));
  });
  let p = await Promise.all(pArr);
  state.val.push(...p);
  proxy.$nextTick(() => {
    typeof Cinput.verify === "function" && Cinput.verify();
  });
};
const chooseImg = async () => {
  let [err, res] = (await uni.chooseImage({
    count: props.maxCount - state.val.length,
  })) as any;
  if (err) {
    uni.showToast({
      title: err.errMsg,
    });
  }
  return res.tempFiles || [];
};
const chooseVideo = () => {
  return new Promise((resvole, inject) => {
    uni.chooseVideo({
      count: props.maxCount - state.val.length,
      compressed: true,
      maxDuration: props.maxDuration,
      success: async (file) => {
        if (file.size > props.videoSize * 1024 * 1000) {
          inject(false);
          return uni.showModal({
            title: "提示",
            content: `请上传${props.videoSize}M以内的视频`,
            showCancel: false,
          });
        }
        // const tempFiles = file.tempFiles[0].tempFilePath;
        const tempFiles = file.tempFilePath;
        // uni.showToast({
        // 	title: '正在上传...',
        // 	icon: 'loading',
        // 	mask: true,
        // 	duration: 10000
        // });
        resvole([
          {
            ...file,
            path: tempFiles,
          },
        ]);
        // uni.uploadFile({
        // 	url: config.mallApiUrl + '/api/FilesApi/UploadFiles',
        // 	filePath: tempFiles,
        // 	name: 'file',
        // 	success: (res) => {
        // 		console.log(videoInfo, 'videoInfo')
        // 		this.$emit('videoInfo', JSON.stringify(videoInfo))
        // 		// this.videoObj.width = file.tempFiles[0].width + 'rpx'
        // 		// this.videoObj.height = file.tempFiles[0].height + 'rpx'
        // 		const data = JSON.parse(res.data);
        // 		// _this.videoUrl = config.mallApiUrl + data.result.webUrl;
        // 		this.videoUrl = data.result.webUrl;
        // 		this.$emit('input', this.videoUrl);
        // 		this.$forceUpdate();
        // 	},
        // 	complete() {
        // 		uni.hideToast();
        // 	}
        // });
      },
    });
  });
};
/**
 * 上传文件
 * @param {string} v 文件路径
 * @param {string} size 文件大小
 */
const uploadFile = (filePath: string) => {
  uni.showToast({
    title: "上传中...",
    icon: "loading",
  });
  return new Promise(async (ress, err) => {
    let apiUrl = props.type === "image" ? props.api : props.vapi;
    if (!apiUrl.includes("http")) {
      apiUrl = import.meta.env.VITE_API_URL + apiUrl;
    }
    uni.uploadFile({
      url: apiUrl,
      filePath,
      name: "file",
      success: (res) => {
        const data = JSON.parse(res.data);
        let url = data.result[props.range_key];
        ress(url);
      },
      fail(error) {
        err(error);
        console.log(error, "error");
      },
      complete() {
        uni.hideToast();
      },
    });
  });
};
</script>

<style lang="scss" scoped>
.c-pload {
  width: 100%;
  // flex: 1;
  position: relative;
  display: inline-flex;
  flex-wrap: wrap;

  .img-box {
    position: relative;

    .img {
      width: 140rpx;
      height: 140rpx;
      margin-bottom: 10rpx;
      margin-right: 10rpx;
    }

    .icon-guanbi {
      position: absolute;
      top: 0;
      right: 10rpx;
      padding: 7rpx 10rpx;
      background: #666;
      color: #fff;
      font-size: 20rpx;
      border-radius: 0 10rpx 0 10rpx;
    }
  }

  .upload-button {
    margin-bottom: 10rpx;
    width: 140rpx;
    height: 140rpx;
    border-radius: 20rpx;
    background: #fff;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    box-shadow: 1px 2px 7px 0px #ccc;
  }
}
</style>